#!/usr/bin/env python3
"""
GitRepository 数据模型
表示 Git 仓库的各种状态和属性
"""

import os
import pathlib
from datetime import datetime
from typing import Dict, Any, Optional


class GitRepository:
    """Git 仓库数据模型"""
    
    def __init__(self, path: str):
        """
        初始化 Git 仓库对象
        
        Args:
            path: 仓库路径
        """
        self.path = path
        self.name = ""
        self.is_valid = False
        self.last_updated = ""
        self.pull_status = "pending"
        self.error_message = ""
        
        # 验证路径并初始化属性
        self.validate_path()
        if self.is_valid:
            self.get_name()
            self.last_updated = datetime.now().isoformat()
    
    def validate_path(self) -> bool:
        """
        验证路径有效性
        
        Returns:
            bool: 路径是否有效
        """
        try:
            # 使用 pathlib 处理路径
            repo_path = pathlib.Path(self.path)
            
            # 检查路径是否存在
            if not repo_path.exists():
                self.error_message = f"路径不存在: {self.path}"
                self.is_valid = False
                return False
            
            # 检查是否为目录
            if not repo_path.is_dir():
                self.error_message = f"路径不是目录: {self.path}"
                self.is_valid = False
                return False
            
            # 检查是否为 Git 仓库（包含 .git 目录）
            git_dir = repo_path / ".git"
            if not git_dir.exists():
                self.error_message = f"不是有效的 Git 仓库: {self.path}"
                self.is_valid = False
                return False
            
            # 使用 realpath 防止路径遍历攻击
            real_path = os.path.realpath(self.path)
            current_path = os.path.realpath(os.getcwd())
            
            if not real_path.startswith(current_path):
                self.error_message = f"路径遍历攻击被阻止: {self.path}"
                self.is_valid = False
                return False
            
            self.is_valid = True
            self.error_message = ""
            return True
            
        except Exception as e:
            self.error_message = f"路径验证失败: {str(e)}"
            self.is_valid = False
            return False
    
    def get_name(self) -> str:
        """
        获取仓库名称
        
        Returns:
            str: 仓库名称
        """
        if not self.is_valid:
            return ""
        
        try:
            # 从路径中提取仓库名称
            path_obj = pathlib.Path(self.path)
            self.name = path_obj.name
            return self.name
        except Exception as e:
            self.error_message = f"获取仓库名称失败: {str(e)}"
            return ""
    
    def get_status(self) -> Dict[str, Any]:
        """
        获取仓库状态
        
        Returns:
            Dict[str, Any]: 仓库状态信息
        """
        if not self.is_valid:
            return {
                "status": "error",
                "error": self.error_message,
                "path": self.path
            }
        
        try:
            # 执行 git status 命令
            import subprocess
            result = subprocess.run(
                ["git", "status", "--porcelain"],
                cwd=self.path,
                capture_output=True,
                text=True,
                timeout=30
            )
            
            if result.returncode == 0:
                return {
                    "status": "clean",
                    "changes": result.stdout.strip(),
                    "path": self.path
                }
            else:
                return {
                    "status": "dirty",
                    "changes": result.stdout.strip(),
                    "error": result.stderr.strip(),
                    "path": self.path
                }
                
        except subprocess.TimeoutExpired:
            return {
                "status": "timeout",
                "error": "命令执行超时",
                "path": self.path
            }
        except Exception as e:
            return {
                "status": "error",
                "error": str(e),
                "path": self.path
            }
    
    def to_dict(self) -> Dict[str, Any]:
        """
        转换为字典格式
        
        Returns:
            Dict[str, Any]: 字典表示
        """
        return {
            "path": self.path,
            "name": self.name,
            "is_valid": self.is_valid,
            "exists": os.path.exists(self.path),
            "is_directory": os.path.isdir(self.path),
            "is_git_repo": self.is_valid,
            "last_updated": self.last_updated,
            "pull_status": self.pull_status,
            "error_message": self.error_message
        }
    
    def __str__(self) -> str:
        """字符串表示"""
        status = "valid" if self.is_valid else "invalid"
        return f"GitRepository(path='{self.path}', name='{self.name}', {status})"
    
    def __repr__(self) -> str:
        """调试表示"""
        return self.__str__()
    
    def __eq__(self, other) -> bool:
        """相等性比较"""
        if not isinstance(other, GitRepository):
            return False
        return self.path == other.path
    
    def __ne__(self, other) -> bool:
        """不等性比较"""
        return not self.__eq__(other)


def test_git_repository():
    """测试 GitRepository 类"""
    print("测试 GitRepository 类...")
    
    # 测试有效仓库
    valid_repo = GitRepository(".")
    print(f"测试仓库: {valid_repo}")
    
    # 测试无效仓库
    invalid_repo = GitRepository("/nonexistent/path")
    print(f"无效仓库: {invalid_repo}")
    
    # 测试当前目录
    current_repo = GitRepository(".")
    print(f"当前目录: {current_repo}")


if __name__ == "__main__":
    test_git_repository()